package com.example.yx1.demo35;

import org.springframework.boot.DefaultBootstrapContext;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringApplicationRunListener;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.io.support.SpringFactoriesLoader;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.List;

public class A35_1 {
    public static void main(String[] args) throws Exception {

        //添加 监听器 ，输出接收到的事件类型
        SpringApplication app = new SpringApplication();
        app.addListeners(event -> System.out.println(event.getClass()));

        List<String> names = SpringFactoriesLoader.loadFactoryNames(SpringApplicationRunListener.class, A35_1.class.getClassLoader());
        for (String name : names) {
            System.out.println(name);

            //调用实现类的事件发布方法之得到对象
            Class<?> clazz = Class.forName(name);
            Constructor<?> constructor = clazz.getConstructor(SpringApplication.class, String[].class);
            SpringApplicationRunListener publisher = (SpringApplicationRunListener) constructor.newInstance(app, args);

            //发布事件
            DefaultBootstrapContext bootstrapContext = new DefaultBootstrapContext();
            publisher.starting(bootstrapContext); // Spring Boot 开始启动
            publisher.environmentPrepared(bootstrapContext,new StandardEnvironment());// 环境信息准备完毕
            GenericApplicationContext context = new GenericApplicationContext(); //创建一个空容器以便测试
            publisher.contextPrepared(context); //在spring容器创建，并调用初始化器之后，发送此事件
            publisher.contextLoaded(context);//所有 bean definition 加载完毕
            context.refresh(); // 容器初始化
            publisher.started(context); //spring 容器初始化完成 （refresh方法之后）
            publisher.running(context);//spring boot  启动完毕

            publisher.failed(context,new Exception("输出失败"));
        }
    }
}
